# coding: utf-8
#import pycurl
#import StringIO

import sys
import re
import urllib
import urllib2

import sqlite3

import sys
import time

def print_same_line(line):
	sys.stdout.flush()
	sys.stdout.write('\r')
	sys.stdout.flush()
	sys.stdout.write( line )
	
class mcBase:
	logger = None

	@classmethod
	def init(cls):
		cls._loadLogger()


	@classmethod
	def _loadLogger(cls):

		import logging

		cls.logger = logging.getLogger('maxcinema')
		hdlr = logging.FileHandler('maxcinema.log')
		formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
		hdlr.setFormatter(formatter)
		cls.logger.addHandler(hdlr)

		cls.logger.setLevel(logging.DEBUG)

		cls.logger.info('Iniciando Maxcinema ...')

		return cls.logger



class mcData:

	dbconn = None

	rx_504 = None
	rx_502 = None

	def __init__(self):

		self.dbconn = sqlite3.connect('app.db')

		self.rx_504 = re.compile('504 Gateway Time-out')
		self.rx_502 = re.compile('502 Bad Gateway')


	def get(self, url, cf = "" , headers = None):
		salida = ""
		intent = 10
		i=0
		while i < intent:
			mcBase.logger.debug("before GET " + url)

			user_agent = 'Mozilla/4.0 (compatible: MSIE 6.0)'

			req = urllib2.Request(url)
			req.add_header('User-Agent', user_agent)

			import fileinput
			import os
			if os.path.exists(cf):
				for line in fileinput.input(cf):
					req.add_header('Set-Cookie', line)
				

			if headers:
				for h in headers:
					req.add_header(h, headers[h])


			response = urllib2.urlopen(req)
			salida = response.read()
			response.close()
			
			if os.path.exists(cf):
				cookie = response.info()			
				cf_file = open(cf, "w")
				for c in cookie.headers:
					m = re.search('Set-Cookie:(.*)', c)				
					if m:
					    cf_file.write(m.group(1))
				cf_file.close()
				
			mcBase.logger.debug("after GET ")

			mcBase.logger.debug(salida)
			m = re.search(self.rx_504 , salida)
			if m != None:
				i = i + 1
				mcBase.logger.debug("Reintento ... #" + str(i)  + " (Gateway Time-out)")
			else:
				m = re.search( self.rx_502, salida)
				if m != None:
					i = i + 1
					mcBase.logger.debug("Reintento ... #" + str(i) + " (Bad Gateway)")
				else:
					i = intent

		return salida

	def post(self,url, post, cf = "", headers = None):

		mcBase.logger.debug("before POST " + url)

		user_agent = 'Mozilla/4.0 (compatible: MSIE 6.0)'

		req = urllib2.Request(url, post)
		req.add_header('User-Agent', user_agent)

		import fileinput
		import os
		if os.path.exists(cf):
			for line in fileinput.input(cf):
				req.add_header('Set-Cookie', line)

		if headers:
			for h in headers:
				req.add_header(h, headers[h])


		response = urllib2.urlopen(req)
		salida = response.read()
		response.close()
		
		if os.path.exists(cf):
			cookie = response.info()			
			cf_file = open(cf, "w")
			for c in cookie.headers:
				m = re.search('Set-Cookie:(.*)', c)				
				if m:
				    cf_file.write(m.group(1))
			cf_file.close()

		mcBase.logger.debug("after POST ")

		return salida


	def down(self, url, output, cf = "cookies.txt" , headers = None):
			
		user_agent = 'Mozilla/4.0 (compatible: MSIE 6.0)'				

		req = urllib2.Request(url)
		req.add_header('User-Agent', user_agent)		

		import fileinput
		import os
		if os.path.exists(cf):
			for line in fileinput.input(cf):
				req.add_header('Set-Cookie', line)
			

		if headers:
			for h in headers:
				req.add_header(h, headers[h])

		response = urllib2.urlopen(req)		
		
		f = open(output, 'wb')
		meta = response.info()
		file_size = int(meta.getheaders("Content-Length")[0])
		
		print "Downloading: %s Bytes: %s" % (output, file_size)

		file_size_dl = 0
		block_sz = 8192
		while True:
			buffer = response.read(block_sz)
			if not buffer:
				break

			file_size_dl += len(buffer)
			f.write(buffer)
			status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
			status = status + chr(8)*(len(status)+1)
			print status,

		f.close()
		


		


class mcMovie:

	###############################
	##	Public Methods
	###############################

	def __init__ (self, service=None, id=None):
			
		##	Publics fields
	
		self.service		= ""

		self.id 		= ""
		self.title		= ""
		self.original_title	= ""
		self.description	= ""

		self.url		= ""
		self.cover_url		= ""

		self.languages		= []
		self.sub_languages	= []
		self.sources		= []
	
		##	Protecteds fields
	
		self._exist_in_db    = False
		self._mcData = mcData()
		self._logger = None
		
		
		if service != None:
			self.service = service

		if id != None:
			self.id = id

		if service != None and id != None:
			if not self.dbLoadInfo() :
				#load Info
				self.loadInfo()

			#Load Sources
			if not self.dbLoadSources() :
				self.loadSources()
			
			#Subtitle
				


	def loadInfo(self):
		self.dbStoreInfo()

	def loadSources(self):
		self.dbDeleteAllSources()
		for s in self.sources:
			self.dbStoreSource(s)

	def loadSubtitles(self):
		pass

	def dbStoreInfo(self):
		conn = self._mcData.dbconn

		c = conn.cursor()

		# Create table
		c.execute('''create table if not exists movies
		(service text, id text, title text, original_title text, description text, url text, cover_url text, primary key(service, id) )''')

		# Insert a row of data
		c.execute("replace into movies values ( ?, ?, ?, ?, ?, ?, ?)" , (self.service, self.id, self.title, self.original_title, self.description, self.url, self.cover_url ) )

		# Save (commit) the changes
		conn.commit()

		c.close()
		
	def dbLoadInfo(self):
		conn = self._mcData.dbconn

		c = conn.cursor()

		# Create table (CHANGE THIS)
		c.execute('''create table if not exists movies
		(service text, id text, title text, original_title text, description text, url text, cover_url text, primary key(service, id) )''')

		# Insert a row of data
		c.execute("select * from movies where id = ? and service = ? ", ( str(self.id), self.service ) )

		for row in c:
			self.title = row[2]
			self.original_title = row[3]
			self.description = row[4]
			self.url = row[5]
			self.cover_url = row[6]
			#Mark
			self._exist_in_db = True

		# Save (commit) the changes
		conn.commit()

		c.close()
		
		return self._exist_in_db

	def dbDeleteAllSources(self):
		
		conn = self._mcData.dbconn

		c = conn.cursor()

		c.execute('''create table if not exists sources
		(service text, id text, url text, server text, definition text, audio_lang text, primary key(service, id, url, definition, audio_lang) )''')
		
		# Delete
		c.execute("delete from sources where id = ? and service = ?;", (self.id , self.service) )

		# Save (commit) the changes
		conn.commit()
		
		c.close()
		

	def dbStoreSource(self, source):
		conn = self._mcData.dbconn

		c = conn.cursor()

		# Create table
		c.execute('''create table if not exists sources
		(service text, id text, url text, server text, definition text, audio_lang text, primary key(service, id, url, definition, audio_lang) )''')
		
		# Insert a row of data
		c.execute("replace into sources values ( ?, ?, ?, ?, ?, ?)" , (source.service, source.id, source.url , source.server, source.definition, source.audio_lang ) )

		# Save (commit) the changes
		conn.commit()

		c.close()
		

	def dbLoadSources(self):
		conn = self._mcData.dbconn

		c = conn.cursor()

		# Create table (CHANGE THIS)
		c.execute('''create table if not exists sources
		(service text, id text, url text, server text, definition text, audio_lang text, primary key(service, id, url, definition, audio_lang) )''')

		# Select rows of data
		c.execute("select * from sources where id = ? and service = ? ", ( str(self.id), self.service ) )
		
		for row in c:
			s = mcSource()
			s.service = self.service
			s.id = self.id
			s.url = row[2]
			s.server = row[3]
			s.definition = row[4]
			s.audio_lang = row[5]
			self.sources.append(s)
			
		c.close()

		if len(self.sources) > 0:
			return True
		else:
			return False


	def dbExistSource(self, server, definition,  audio_lang):
		conn = self._mcData.dbconn

		c = conn.cursor()

		# Create table (CHANGE THIS)
		c.execute('''create table if not exists sources
		(service text, id text, url text, server text, definition text, audio_lang text, primary key(service, id, url, definition, audio_lang) )''')

		# Select rows of data
		c.execute("select count(*) from sources where id = ? and service = ? and server = ? and definition = ? and audio_lang = ? and url <> '' ", ( str(self.id), self.service , server, definition,  audio_lang ) )
		
		rows = c.fetchone()
					
		c.close()

		if rows > 0:
			return True
		else:
			return False



	def reCaptcha(self, key, url_base, cf = ''):
	
		import os
		print "Captcha\n"

		url = "http://www.google.com/recaptcha/api/challenge?k="+key

		salida = self._mcData.get(url)

		#Server
		SERVER=""
		rec_server = re.compile('server[[\s?]:[\s?]\'([^\']*)\'')
		match = re.search(rec_server, salida)

		if match != None:
		    SERVER=match.group(1)

		#Server
		SERVER=""
		rec_server = re.compile('server[[\s?]:[\s?]\'([^\']*)\'')
		match = re.search(rec_server, salida)

		if match != None:
		    SERVER=match.group(1)

		#Server
		CHALLENGE=""
		rec_challenge = re.compile('challenge[[\s?]:[\s?]\'([^\']*)\'')
		match = re.search(rec_challenge, salida)

		if match != None:
		    CHALLENGE=match.group(1)

		FILENAME = "recaptcha.jpg"    

		URL=SERVER + "image?c=" + CHALLENGE   

		os.system("wget '" + URL + "' -O " + FILENAME)

		import subprocess
		import signal
		
		pipe = subprocess.Popen(['display', FILENAME])
		#print os.system("display "+ FILENAME + " &")

		print "Ingrese\n"
		captcha = raw_input('--> ')
		
		os.kill(pipe.pid, signal.SIGTERM)

		data = {

		'recaptcha_response_field': captcha,	
		'recaptcha_challenge_field': CHALLENGE

		}

		post = urllib.urlencode(data)

		print "\nCaptcha:"
		print captcha

		print "\nChallenge:"
		print CHALLENGE


		print "\n"

		#post
		salida = self._mcData.post(url_base, post, cf, { 'X-Requested-With': 'XMLHttpRequest', 'Referer': url_base })
		return salida
		

	def bayFile(self, url):
	
		import os
		print "Bayfile\n"	

		salida = self._mcData.get(url)
		
		vfid=""
		rec_vfid = re.compile('var vfid =([^;]*)')
		match = re.search(rec_vfid, salida)
		if match != None:
		    vfid=match.group(1)		

		print "vfid :" + vfid
		
		delay=""
		rec_delay = re.compile('var delay =([^;]*)')
		match = re.search(rec_delay, salida)
		if match != None:
		    delay=match.group(1)		

		print "delay :" + delay
		
		
		data = {'action': "startTimer", 'vfid': vfid}

		post = urllib.urlencode(data)
		
		ajax_url = "http://bayfiles.com/ajax_download?" + post
		
		print "Url: " + ajax_url
		
		salida = self._mcData.get(ajax_url, post)
		
		#~ print salida
		
		import json
		jsalida = json.loads(salida)
#~ 
		#~ import pprint		
		#~ pprint.pprint(jsalida['token'])		
		#~ 
		#~ for i in jsalida:	
			#~ print i			
			#~ pprint.pprint(jsalida[i])
		
		token = jsalida['token']
		
		print "Token: " + token		
		
		
		print "WAIT %s \n" % delay		
		for i in range(int(delay)):
			print_same_line("[Link] Waiting: %d  " % int (int(delay)-i) )			
			time.sleep(1)			
		print_same_line( "[Link] Ready: ")			
		
		
		data = {'action': "getLink", 'vfid': vfid, 'token' :  token}
		post = urllib.urlencode(data)		
		ajax_url = "http://bayfiles.com/ajax_download?" + post		
		print "Url: " + ajax_url		
		salida = self._mcData.get(ajax_url, post)
		

		print salida


		"""<div style="text-align: center;"><input type="button" style="padding: 6px 16px; font-size: 1.3em;" onclick="javascript:window.location.href = 'http://h5.baycdn.com/dl/0c95993e/4f46aab2/200/0/613661/hlS3Gk/1b5b1de774f91659b7fa0fcc1b0baca649ab0fd8/refined-5050-720p.mp4';" value="Start Download" /></div>"""




	###############################
	##	Class Methods
	###############################

	@staticmethod
	def search(name):
		result = []
		return result

	@staticmethod
	def news():
		result = []
		return result

	@staticmethod
	def featured():
		result = []
		return result


class mcSource:
	service         = ""
	id		= ""
	url		= ""
	server		= ""
	definition 	= ""
	is_hd		= False
	audio_lang 	= ""





#-----------------------
# Functions
#-----------------------
def dump(obj):
  '''return a printable representation of an object for debugging'''
  newobj=obj
  if '__dict__' in dir(obj):
    newobj=obj.__dict__
    if ' object at ' in str(obj) and not newobj.has_key('__type__'):
      newobj['__type__']=str(obj)
    for attr in newobj:
      newobj[attr]=dump(newobj[attr])
  return newobj

def listar(lista, cols):

	for list_item in cols:
		sys.stdout.write( '+' )
		for i in range(list_item['chars']):
			sys.stdout.write( '-' )

		sys.stdout.write( '--' )

	sys.stdout.write( '+' )
	sys.stdout.write( '\n' )

	for list_item in cols:
		sys.stdout.write( '|' )

		value = list_item['name']
		if 'title' in list_item:
			value = list_item['title']

		chars = list_item['chars']

		align = 'left'
		if 'align' in list_item:
			align = list_item['align']

		if align == 'left':
			value = value.ljust( chars )
		if align == 'right':
			value = value.rjust( chars )

		sys.stdout.write( ' ' + value + ' ' )

	sys.stdout.write( '|' )
	sys.stdout.write( '\n' )

	for list_item in cols:
		sys.stdout.write( '+' )
		for i in range(list_item['chars']):
			sys.stdout.write( '-' )
		sys.stdout.write( '--' )

	sys.stdout.write( '+' )
	sys.stdout.write( '\n' )

	#import string
	#valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)

	import unicodedata


	for s in lista:
		for list_item in cols:
			sys.stdout.write( '|' )
			value = str(s.__dict__[ list_item['name'] ])
			chars = list_item['chars']
			if len(value) > chars:
				value = s.__dict__[ list_item['name'] ][:chars-4] + ' ...'

			try:
				#value = ''.join(c for c in value if c in valid_chars)
				value = ''.join((c for c in unicodedata.normalize('NFD', unicode(value, 'utf-8') ) if unicodedata.category(c) != 'Mn'))
				#value = ''.join((c for c in unicodedata.normalize('NFD', value.encode( "utf8" ) ) if unicodedata.category(c) != 'Mn'))
			except:
				value = value = ''.join((c for c in unicodedata.normalize('NFD', value ) if unicodedata.category(c) != 'Mn'))

			align = 'left'
			if 'align' in list_item:
				align = list_item['align']
			if align == 'left':
				value = value.ljust( chars )

			if align == 'right':
				value = value.rjust( chars )

			sys.stdout.write( ' ' + value +  ' ')

		sys.stdout.write( '|' )
		sys.stdout.write( '\n' )

	for list_item in cols:
		sys.stdout.write( '+' )
		for i in range(list_item['chars']):
			sys.stdout.write( '-' )
		sys.stdout.write( '--' )

	sys.stdout.write( '+' )
	sys.stdout.write( '\n' )


def detallar(object, filas, width_tit, width_data):
	
	sys.stdout.write( '+' )
	for i in range(width_tit):
		sys.stdout.write( '-' )  
	sys.stdout.write( '+' )
	for i in range(width_data):
		sys.stdout.write( '-' )  
	sys.stdout.write( '+' )
	
	for list_item in filas:		

		sys.stdout.write( '\n' )
		sys.stdout.write( '|' )

		value = list_item['name']
		if 'title' in list_item:
			value = list_item['title']

		chars = width_tit - 2

		align = 'right'
		if 'align' in list_item:
			align = list_item['align']

		if align == 'left':
			value = value.ljust( chars )
		if align == 'right':
			value = value.rjust( chars )

		sys.stdout.write( ' ' + value + ' ' )
		
		sys.stdout.write( '|' )
		
		value = object.__dict__[ list_item['name'] ]
		value = value.ljust( width_data - 2 )
		sys.stdout.write( ' ' + value.encode('utf8') + ' ' )
		
		sys.stdout.write( '|' )
	
	sys.stdout.write( '\n' )
	sys.stdout.write( '+' )
	for i in range(width_tit):
		sys.stdout.write( '-' )  
	sys.stdout.write( '+' )
	for i in range(width_data):
		sys.stdout.write( '-' )  
	sys.stdout.write( '+' )	
	sys.stdout.write( '\n' )
	pass

